﻿using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
using E4RPManager.DataSets;
using E4RPTools;

namespace E4RPManager
{
    public class Controller
    {
        private const string ProductName = "E4RPManager";

        private SqlConnection _connection;

        public IWin32Window OwnerWindow { get; set; }

        public string LogFile { get; set; }


        private void FixConnection()
        {
            if (_connection.State == ConnectionState.Open)
                _connection.Close();
            _connection.Open();
        }


        public void SetLogFile()
        {
            try
            {
                LogFile = ConfigurationManager.AppSettings["LogFile"];
            }
            catch (Exception)
            {
                LogFile = "";
                ExceptionPublisher.ShowErrorMessage(OwnerWindow, "Não foi possível obter o ficheiro de logs.", ProductName);
            }
        }

        public bool Login()
        {
            var dataSource = ConfigurationManager.AppSettings["FonteDados"];
            var databaseName = ConfigurationManager.AppSettings["NomeBaseDados"];
            var userName = ConfigurationManager.AppSettings["Utilizador"];
            var password = ConfigurationManager.AppSettings["Senha"];
            var connectionString = "Data Source=" + dataSource + ";Initial Catalog=" + databaseName + ";User ID=" + userName + ";Password=" + password + ";MultipleActiveResultSets=True;";
            try
            {
                _connection = new SqlConnection(connectionString);
                _connection.Open();
            }
            catch (Exception e)
            {
                ExceptionPublisher.PublishAndShowErrorMessage(OwnerWindow, e, LogFile, ProductName, "Não foi possível ligar à base de dados.");
                return false;
            }
            return true;
        }

        public void CloseConnections()
        {
            _connection.Close();
        }

        #region Product
        
        public ProdutoDataSet GetProducts()
        {
            var dataSet = new ProdutoDataSet();
            foreach (Product product in Enum.GetValues(typeof(Product)))
                dataSet.Produto.AddProdutoRow((int)product, product.ToString());
            return dataSet;
        }
        
        #endregion   

        #region Partner

        private void OnPartnerSaved()
        {
            EventHandler<EventArgs> saved = PartnerSaved;
            if (saved != null)
                saved(this, new EventArgs());
        }

        public event EventHandler<EventArgs> PartnerSaved;

        public ParceiroDataSet GetPartners()
        {
            FixConnection();
            var sqlTransaction = _connection.BeginTransaction();
            try
            {
                ParceiroDataSet dataSet = Database.GetPartners(sqlTransaction);
                sqlTransaction.Commit();
                return dataSet;
            }
            catch (Exception e)
            {
                sqlTransaction.Rollback();
                ExceptionPublisher.PublishAndShowErrorMessage(OwnerWindow, e, LogFile, ProductName, "Não foi possível ler a lista de parceiros.");
                return new ParceiroDataSet();
            }
        }

        public ParceiroDataSet GetPartner(long id)
        {
            FixConnection();
            var sqlTransaction = _connection.BeginTransaction();
            try
            {
                ParceiroDataSet dataSet = Database.GetPartner(sqlTransaction, id);
                sqlTransaction.Commit();
                return dataSet;
            }
            catch (Exception e)
            {
                sqlTransaction.Rollback();
                ExceptionPublisher.PublishAndShowErrorMessage(OwnerWindow, e, LogFile, ProductName, "Não foi possível ler o parceiro.");
                return new ParceiroDataSet();
            }
        }

        public Result IsPartnerValid(ParceiroDataSet dataSet)
        {
            return Validator.IsPartnerValid(dataSet);
        }

        public void SavePartner(ParceiroDataSet dataset)
        {
            FixConnection();
            var sqlTransaction = _connection.BeginTransaction();
            try
            {
                Database.SavePartner(sqlTransaction, dataset.Parceiro[0]);
                sqlTransaction.Commit();
                OnPartnerSaved();
            }
            catch (Exception e)
            {
                sqlTransaction.Rollback();
                ExceptionPublisher.PublishAndShowErrorMessage(OwnerWindow, e, LogFile, ProductName, "Não foi possível gravar o parceiro.");
            }
        }

        #endregion   

        #region Client

        private void OnClientSaved()
        {
            EventHandler<EventArgs> saved = ClientSaved;
            if (saved != null)
                saved(this, new EventArgs());
        }

        public event EventHandler<EventArgs> ClientSaved;

        public ClienteDataSet GetClients()
        {
            FixConnection();
            var sqlTransaction = _connection.BeginTransaction();
            try
            {
                ClienteDataSet dataSet = Database.GetClients(sqlTransaction);
                sqlTransaction.Commit();
                return dataSet;
            }
            catch (Exception e)
            {
                sqlTransaction.Rollback();
                ExceptionPublisher.PublishAndShowErrorMessage(OwnerWindow, e, LogFile, ProductName, "Não foi possível ler a lista de clientes.");
                return new ClienteDataSet();
            }
        }

        public ClienteDataSet GetClient(long id)
        {
            FixConnection();
            var sqlTransaction = _connection.BeginTransaction();
            try
            {
                ClienteDataSet dataSet = Database.GetClient(sqlTransaction, id);
                sqlTransaction.Commit();
                return dataSet;
            }
            catch (Exception e)
            {
                sqlTransaction.Rollback();
                ExceptionPublisher.PublishAndShowErrorMessage(OwnerWindow, e, LogFile, ProductName, "Não foi possível ler o cliente.");
                return new ClienteDataSet();
            }
        }

        public Result IsClientValid(ClienteDataSet dataSet)
        {
            return Validator.IsClientValid(dataSet);
        }

        public void SaveClient(ClienteDataSet dataset)
        {
            FixConnection();
            var sqlTransaction = _connection.BeginTransaction();
            try
            {
                Database.SaveClient(sqlTransaction, dataset.Cliente[0]);
                Database.UpdateClientProducts(sqlTransaction, dataset.Cliente[0].Id, dataset.ClienteProduto);
                sqlTransaction.Commit();
                OnClientSaved();
            }
            catch (Exception e)
            {
                sqlTransaction.Rollback();
                ExceptionPublisher.PublishAndShowErrorMessage(OwnerWindow, e, LogFile, ProductName, "Não foi possível gravar o cliente.");
            }
        }

        #endregion    
 

    }
}
